package com.haoyun.mirage.user.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.haoyun.common.constant.CommonConstant;
import com.haoyun.common.core.BaseException;
import com.haoyun.mirage.user.common.utils.TreeUtil;
import com.haoyun.mirage.user.mapper.SysDeptMapper;
import com.haoyun.mirage.user.mapper.SysDeptRelationMapper;
import com.haoyun.mirage.user.mapper.SysRoleDeptMapper;
import com.haoyun.mirage.user.mapper.SysUserMapper;
import com.haoyun.mirage.user.model.dto.DeptDTO;
import com.haoyun.mirage.user.model.dto.UserDTO;
import com.haoyun.mirage.user.model.entity.SysDept;
import com.haoyun.mirage.user.model.entity.SysDeptRelation;
import com.haoyun.mirage.user.model.entity.SysRoleDept;
import com.haoyun.mirage.user.model.vo.DeptTree;
import com.haoyun.mirage.user.service.ISysDeptService;
import com.xiaoleilu.hutool.collection.CollectionUtil;
import com.xiaoleilu.hutool.lang.Assert;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 部门管理 服务实现类
 * </p>
 *
 * @author twg
 * @since 2018-05-30
 */
@Service
public class SysDeptServiceImpl extends ServiceImpl<SysDeptMapper, SysDept> implements ISysDeptService {

    @Autowired
    private SysDeptMapper deptMapper;
    @Autowired
    private SysUserMapper userMapper;
    @Autowired
    private SysDeptRelationMapper deptRelationMapper;
    @Autowired
    private SysRoleDeptMapper roleDeptMapper;

    /**
     * 添加信息部门
     *
     * @param dept 部门
     * @return
     */
    @Override
    @Transactional
    public Boolean insertDept(SysDept dept) {
        if (this.isExist(dept.getDeptName())) {
            throw new BaseException("部门 [" + dept.getDeptName() + "] 已存在");
        }
        this.insert(dept);
        this.insertDeptRelation(dept);
        return Boolean.TRUE;
    }

    /**
     * 维护部门关系
     *
     * @param sysDept 部门
     */
    private void insertDeptRelation(SysDept sysDept) {
        Assert.notNull(sysDept.getId(), "部门id不能为空");
        Assert.notNull(sysDept.getParentId(), "部门父节点不能为空");
        //增加部门关系表
        SysDeptRelation deptRelation = new SysDeptRelation();
        deptRelation.setDescendant(sysDept.getParentId());
        List<SysDeptRelation> deptRelationList = deptRelationMapper.selectList(new EntityWrapper<>(deptRelation));
        for (SysDeptRelation sysDeptRelation : deptRelationList) {
            SysDeptRelation _deptRelation = new SysDeptRelation();
            _deptRelation.setDescendant(sysDept.getId());
            _deptRelation.setAncestor(sysDeptRelation.getAncestor());
            deptRelationMapper.insert(_deptRelation);
        }
        //自己也要维护到关系表中
        SysDeptRelation own = new SysDeptRelation();
        own.setDescendant(sysDept.getId());
        own.setAncestor(sysDept.getId());
        deptRelationMapper.insert(own);
    }

    /**
     * 删除部门
     *
     * @param id 部门 ID
     * @return 成功、失败
     */
    @Override
    @Transactional
    public Boolean deleteDeptById(Long id) {
        List<UserDTO> userDTOS = userMapper.findUserByCompIdOrDepId(id);
        if (CollectionUtil.isNotEmpty(userDTOS)){
            throw new BaseException("该部门已存在用户，不能删除");
        }
        SysDept sysDept = new SysDept();
        sysDept.setId(id);
        sysDept.setIsDeleted(CommonConstant.STATUS_DEL);
        this.deleteById(sysDept);
        deptRelationMapper.deleteDeptRelation(id);
        SysRoleDept roleDept = new SysRoleDept();
        roleDept.setDeptId(id);
        roleDeptMapper.delete(new EntityWrapper<>(roleDept));
        return Boolean.TRUE;
    }

    /**
     * 更新部门
     *
     * @param sysDept 部门信息
     * @return 成功、失败
     */
    @Override
    @Transactional
    public Boolean updateDeptById(SysDept sysDept) {
        //更新部门状态
        this.updateById(sysDept);
        //删除部门关系
        deptRelationMapper.deleteDeptRelation(sysDept.getId());
        //新建部门关系
        this.insertDeptRelation(sysDept);
        return Boolean.TRUE;
    }

    /**
     * 查询部门树
     *
     * @param sysDeptEntityWrapper
     * @return 树
     */
    @Override
    public List<DeptTree> selectListTree(EntityWrapper<SysDept> sysDeptEntityWrapper) {
        return getDeptTree(this.selectList(sysDeptEntityWrapper), 0L);
    }


    @Override
    public List<DeptDTO> findDeptByIds(List<Long> ids) {
        List<SysDept> depts = deptMapper.selectBatchIds(ids);
        List<DeptDTO> deptDTOS = Lists.newArrayListWithCapacity(depts.size());
        DeptDTO deptDTO = null;
        for (SysDept dept : depts) {
            deptDTO = new DeptDTO();
            BeanUtils.copyProperties(dept, deptDTO);
            deptDTOS.add(deptDTO);
        }
        return deptDTOS;
    }

    @Override
    public Boolean isExist(String deptName) {
        Assert.notBlank(deptName, "部门名称不能为空");
        SysDept dept = new SysDept();
        dept.setDeptName(deptName);
        SysDept sysDept = deptMapper.selectOne(dept);
        if (sysDept == null) {
            return Boolean.FALSE;
        }
        return Boolean.TRUE;
    }


    /**
     * 构建部门树
     *
     * @param deptList 部门
     * @param root     根节点
     * @return
     */
    private List<DeptTree> getDeptTree(List<SysDept> deptList, Long root) {
        List<DeptTree> trees = new ArrayList<>();
        DeptTree node;
        for (SysDept dept : deptList) {
            if (dept.getParentId().equals(dept.getId())) {
                continue;
            }
            node = new DeptTree();
            node.setId(dept.getId());
            node.setParentId(dept.getParentId());
            node.setName(dept.getDeptName());
            trees.add(node);
        }
        return TreeUtil.build(trees, root);
    }
}
